using System;
using System.Xml; 
using System.IO;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using Microsoft.Win32;

namespace ClipLink
{
	/// <summary>
	/// Summary description for Form1.
	/// </summary>
	public class MainForm : System.Windows.Forms.Form
	{
		[System.Runtime.InteropServices.DllImport("User32.dll")]
		private static extern short GetAsyncKeyState(System.Windows.Forms.Keys vKey); // Keys enumeration
		[System.Runtime.InteropServices.DllImport("User32.dll")]
		private static extern short GetAsyncKeyState(System.Int32 vKey);

		private static ArrayList urlsArray   = new ArrayList ();
		private static ArrayList menuNames   = new ArrayList ();

		private static Rgl.Components.ClipboardViewer viewer;
		/// <summary>
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.Container components = null;
		static private System.Windows.Forms.NotifyIcon notify = new NotifyIcon();
		static private System.Windows.Forms.ContextMenu BaseMenu;

		public MainForm()
		{
			//
			// Required for Windows Form Designer support
			//
			InitializeComponent();

			//
			// TODO: Add any constructor code after InitializeComponent call
			//
			
		}

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if (components != null) 
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			// 
			// Form1
			// 
			this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
			this.ClientSize = new System.Drawing.Size(292, 273);
			this.Name = "Form1";
			this.Text = "MainForm";

		}
		#endregion

		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		[STAThread]
		static void Main() 
		{
			InitSettings ();
			// load icon from resource
			System.Reflection.Assembly myApp = System.Reflection.Assembly.GetExecutingAssembly();
			System.IO.Stream ResStream = myApp.GetManifestResourceStream("ClipLink.Tray.ico");
			notify.Icon = new System.Drawing.Icon(ResStream);
			notify.Visible = true;
			notify.Text = "ClipLink";

			// build menu
			notify.ContextMenu = BuildMenu();

			viewer = new Rgl.Components.ClipboardViewer();
			viewer.ClipboardChanged += new Rgl.Components.VoidEventHandler(Viewer_ClipboardChanged);
			viewer.Enabled = true; // Enable clipboard viewing
			// start application
			Application.Run();

			viewer.Dispose();
		}

		private static void InitSettings () {
			try 
			{
				XmlTextReader reader = new XmlTextReader ("settings.xml");
				while (reader.Read()) {
					switch (reader.NodeType) {
						case XmlNodeType.Element:
							Hashtable attributes = new Hashtable ();
							string strURI= reader.NamespaceURI;
							string elemName= reader.Name;
							string menuName = "";
							string url = "";
							string def = "";
							if (reader.HasAttributes) {
								for (int i = 0; i < reader.AttributeCount; i++)
								{
									reader.MoveToAttribute(i);
									if (reader.Name == "name")
										menuName = reader.Value;
									else if (reader.Name == "url") {
										url = reader.Value;
										url = url.Replace ("&amp;", "&");
									} else if (reader.Name == "default")
										def = reader.Value;
								}
							}
							if (elemName == "menu" && def == "1") {
								urlsArray.Insert (0, url);	
								menuNames.Insert (0, menuName);								
							} else if (elemName == "menu") {							
								urlsArray.Add (url);	
								menuNames.Add (menuName);
							}
							break;
						default:
							break;
					}
				}
			} catch (XmlException e) {
				throw new Exception ("Error occured during parsing settings.xml :"  + e.Message);
			}

		}

		private static void Viewer_ClipboardChanged() {
			if ((GetAsyncKeyState (0x01) & 0x8000) > 0) {
				OpenURL (0);
			}
			//PopulateTreeNodes(clipboardNativeNode, clipboardConvertNode, Clipboard.GetDataObject());
		}

		private static System.Windows.Forms.ContextMenu BuildMenu()
		{
			BaseMenu = new System.Windows.Forms.ContextMenu();
			System.Windows.Forms.MenuItem m;

			string[] keys = (string []) menuNames.ToArray (typeof (System.String));

			foreach (string s in keys) {
				// retrieve and build menu item
				m = new MenuItem(s,new System.EventHandler(Jump));
				BaseMenu.MenuItems.Add(m);
			}


			m = new MenuItem("-",new System.EventHandler(QuitApp));
			BaseMenu.MenuItems.Add(m);
			m = new MenuItem("Quit",new System.EventHandler(QuitApp));
			BaseMenu.MenuItems.Add(m);
			return BaseMenu;
		}

		private static void Jump(object sender, System.EventArgs e) 
		{
			try 
			{
				int index = ((MenuItem)sender).Index;
				OpenURL (index);
				
			}
			catch (Exception err)
			{
				MessageBox.Show(err.Message,"Error");
			}
		}

		private static void OpenURL (int index) {
			try {
				string s = (string)Clipboard.GetDataObject().GetData("System.String",true);
				s = String.Format ((string) urlsArray [index], s);
				new BrowserForm (s).Show ();
			} catch (Exception err) {
				MessageBox.Show(err.Message,"Error");
			}
		}
		
		private static void QuitApp(object sender, System.EventArgs e) 
		{
			Application.Exit();			
		}
	}
}
